package com.parking.stall.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.parking.common.core.model.PageInfo;
import com.parking.common.core.model.StateData;
import com.parking.stall.client.dto.SelectCertifiedInfoDTO;
import com.parking.stall.client.dto.SelectRentersDTO;
import com.parking.stall.client.dto.SelectRentersInfoDTO;
import com.parking.stall.dto.CertifiedSelectStallCheckDTO;
import com.parking.stall.dto.PlatformSelectStallCheckDTO;
import com.parking.stall.dto.RentersSelectStallCheckDTO;
import com.parking.stall.entity.StallCheck;
import com.parking.stall.dao.StallCheckMapper;
import com.parking.stall.entity.StallInfo;
import com.parking.stall.exception.StallException;
import com.parking.stall.exceptionCode.StallExceptionCode;
import com.parking.stall.param.*;
import com.parking.stall.service.StallCheckService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.parking.stall.service.call.PageInfoCheck;
import com.parking.stall.service.call.ServeCallClass;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 彭于晏
 * @since 2023年11月29日
 */
@Service
public class StallCheckServiceImpl extends ServiceImpl<StallCheckMapper, StallCheck> implements StallCheckService {

    /**
     * stallCheckMapper：车位审核mapper
     * stallInfoMapper:车位信息mapper
     * serveCallClass:服务调用类
     * rabbitTemplate：rabbitMq消息队列
     * pageInfoSet:分页（当前页，当前页数）设置工具包
     */

    @Autowired
    private StallCheckMapper stallCheckMapper;

    @Autowired
    private ServeCallClass serveCallClass;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private PageInfoCheck pageInfoCheck;
    /**
     * add:出租客申请车位入驻物业     *
     * @param param:出租客车位申请参数类
     * @return true/false
     * @throws Exception
     */
    @Override
    @Transactional//普通事务注解
    public Boolean add(AddStallCheckParam param) throws Exception {
        //信息参数存在判断
        if (param.getCertifiedInfoId()==null
                ||param.getStallType()==null
                ||!StringUtils.hasLength(param.getRentersInfoCard())
                ||!StringUtils.hasLength(param.getRentersRealName())
                ||!StringUtils.hasLength(param.getStallInfoArea())
                ||param.getStallInfoNum()==null
                ||param.getStallInfoNum()==0
                ||!StringUtils.hasLength(param.getStallBuyProve())) {
            throw new StallException(StallExceptionCode.STALL_APPLY_FOR_PARAM_NOT_EXISTS);//请完善车位信息
        }

        //获取：出租客账号信息对象（对象、账号状态的判断）
        SelectRentersDTO rentersDTO = serveCallClass.rentersCall(param.getRentersId());
        if (rentersDTO.getRentersState()!= StateData.RENDERS_STATE_ENABLE) {
            throw new StallException(StallExceptionCode.ACCOUNT_NOT_ENABLE);//账号已禁用或已删除
        }

        //获取：出租客信息对象（对象、实名状态、个人中心物业信息的判断）
        SelectRentersInfoDTO rentersInfoDTO = serveCallClass.rentersInfoCall(param.getRentersId());
        if (rentersInfoDTO==null) {
            throw new StallException(StallExceptionCode.RENTERS_INFO_NO_EXISTS);//出租客信息对象
        }
        if (rentersInfoDTO.getRentersRealNameState()== StateData.RENTERS_REAL_NAME_STATE_YES) {
            throw new StallException(StallExceptionCode.NOT_RENTERS_REAL_NAME);//出租客未实名
        }
        if (rentersInfoDTO.getCertifiedInfoId()==null ) {
            throw new StallException(StallExceptionCode.CERTIFIED_INFO_NOT_FULL);//请先完善个人信息中物业信息
        }
        if(rentersInfoDTO.getCertifiedInfoId()!=param.getCertifiedInfoId()){
            throw new StallException(StallExceptionCode.CERTIFIED_INFO_ERROR);//物业信息不符
        }
        //获取：车位审核对象（对象、状态的判断）
        StallCheck stallCheck1 = stallCheckMapper.selectOne(new QueryWrapper<StallCheck>()
                .eq("stall_info_num", param.getStallInfoNum())
                .eq("stall_info_area",param.getStallInfoArea()));
        if (stallCheck1!=null ) {
            if (stallCheck1.getStallCheckState()== StateData.RENTERS_CHECK_WAIT) {
                throw new StallException(StallExceptionCode.STALL_CHECK_ALREADY_WAIT);//车位已申请,不可重复申请
            }
            if (stallCheck1.getStallCheckState()== StateData.RENTERS_CHECK_PASS) {
                throw new StallException(StallExceptionCode.STALL_CHECK_ALREADY_PASS);//车位已通过,不可再申请
            }
            if (stallCheck1.getStallCheckState()== StateData.RENTERS_CHECK_NO_PASS) {
                update(new UpdateWrapper<StallCheck>()
                        .eq("stall_info_num", param.getStallInfoNum())
                        .eq("stall_info_area",param.getStallInfoArea())
                        .set("stall_check_state",StateData.RENTERS_CHECK_WAIT)
                        .set("stall_check_note",""));
                return true;
            }
        }

        //保存数据库
        StallCheck stallCheck = new StallCheck();
        stallCheck.setCertifiedInfoId(param.getCertifiedInfoId());//物业信息id
        stallCheck.setStallCheckState(StateData.RENTERS_CHECK_WAIT);//审核状态
        stallCheck.setStallBuyProve(param.getStallBuyProve());//车位购买证明
        stallCheck.setRentersInfoId(rentersInfoDTO.getRentersInfoId());//出租客信息id
        stallCheck.setRentersInfoCard(param.getRentersInfoCard());//出租客身份证号
        stallCheck.setRentersRealName(param.getRentersRealName());//出租客真实姓名
        stallCheck.setStallInfoNum(param.getStallInfoNum());//出租客车位编号
        stallCheck.setStallInfoArea(param.getStallInfoArea());//出租客车位区域
        stallCheck.setStallType(param.getStallType());//车位类型
        save(stallCheck);
        return true;
    }

    /**
     *stallCheck:物业审核出租客申请
     * @param param:物业审核出租客申请参数类
     * @return:true/false
     * @throws Exception
     */
    @Override
    @Transactional//普通事务注解
    public Boolean stallCheck(CertifiedCheckStallParam param) throws Exception {
        //判断参数是否为空
        if (param.getStallCheckId()==null||param.getStallCheckState()==null) {
            throw new StallException(StallExceptionCode.STALL_CHECK_PARAM_NOT_EXISTS);//请完善车位审核信息
        }

        //获取：车位审核信息（对象、状态、退回原因的判断）
        StallCheck stallCheck = getById(param.getStallCheckId());
        if (stallCheck==null) {
            throw new StallException(StallExceptionCode.STALL_CHECK_OBJECT_NOT_EXISTS);//车位审核对象不存在
        }

        UpdateWrapper<StallCheck> wrapper = new UpdateWrapper<>();
        wrapper.eq("stall_check_id", param.getStallCheckId());
        wrapper.set("stall_check_state",param.getStallCheckState());
        if (stallCheck.getStallCheckState()== StateData.RENTERS_CHECK_WAIT) {//数据库状态
            if (param.getStallCheckState()== StateData.RENTERS_CHECK_PASS){
                wrapper.set("stall_check_note","");
                update(wrapper);
                //消息队列
                StallInfo stallInfo = BeanUtil.toBean(stallCheck, StallInfo.class);
                stallInfo.setStallUpDownState(StateData.STALL_STATE_DOWN);
                HashMap<String, Object> map = new HashMap<>();
                map.put("stallInfo",stallInfo);
                map.put("stallCheck",stallCheck);
                rabbitTemplate.convertAndSend("AddStallInfoRabbitMQ",map);

            }else if (param.getStallCheckState()== StateData.RENTERS_CHECK_NO_PASS){
                if (!StringUtils.hasLength(param.getStallCheckNote())) {
                    throw new StallException(StallExceptionCode.STALL_CHECK_NOTE_NOT_EXISTS);
                }
                wrapper.set("stall_check_note",param.getStallCheckNote());
                update(wrapper);
            }else{
                throw new StallException(StallExceptionCode.STALL_CHECK_STATE_PARAM_ERROR);//车位审核参数状态错误
            }
        }else if (stallCheck.getStallCheckState()== StateData.RENTERS_CHECK_PASS){//数据库状态
            if (param.getStallCheckState()== StateData.RENTERS_CHECK_PASS){
                throw new StallException(StallExceptionCode.STALL_CHECK_ALREADY_PASS);//车位已通过不可重复通过
            }else if (param.getStallCheckState()== StateData.RENTERS_CHECK_NO_PASS){
                throw new StallException(StallExceptionCode.STALL_CHECK_PASS_NOT_NO_PASS);//车位已通过不可退回
            }else{
                throw new StallException(StallExceptionCode.STALL_CHECK_STATE_PARAM_ERROR);//车位审核参数状态错误
            }
        }else if (stallCheck.getStallCheckState()== StateData.RENTERS_CHECK_NO_PASS){//数据库状态
            if (param.getStallCheckState()== StateData.RENTERS_CHECK_PASS){
                throw new StallException(StallExceptionCode.STALL_CHECK_NO_PASS_NOT_PASS);//车位已退回不可通过
            }else if (param.getStallCheckState()== StateData.RENTERS_CHECK_NO_PASS){
                throw new StallException(StallExceptionCode.STALL_CHECK_ALREADY_NO_PASS);//车位已退回不可重复退回
            }else{
                throw new StallException(StallExceptionCode.STALL_CHECK_STATE_PARAM_ERROR);//车位审核参数状态错误
            }
        }else{
            throw new StallException(StallExceptionCode.STALL_CHECK_STATE_SQL_ERROR);//车位审核状态数据库数据错误
        }
        return true;
    }

    /**
     *stallCheckUpdate: 出租客修改车位审核申请信息
     * @param param：出租客修改车位审核申请信息参数对象
     * @return:true/false
     * @throws Exception
     */
    @Override
    @Transactional//普通事务注解
    public Boolean stallCheckUpdate(CheckStallUpdateParam param) throws Exception{
        //参数判断
        if (param.getStallCheckId()==null
                &&param.getStallCheckId()==0
                && param.getCertifiedInfoId()==null
                && param.getCertifiedInfoId()==0
                && param.getStallType()==null
                && !StringUtils.hasLength(param.getStallInfoArea())
                && !StringUtils.hasLength(param.getStallBuyProve())
                && param.getStallInfoNum()==null
                && param.getStallInfoNum()==0
                && !StringUtils.hasLength(param.getRentersInfoCard())
                && !StringUtils.hasLength(param.getRentersRealName())) {
            throw new StallException(StallExceptionCode.STALL_CHECK_UPDATE_PARAM_NOT_EXISTS);//请完善车位审核的修改信息
        }

        //获取：车位审核（对象，状态的判断）
        StallCheck stallCheck = getById(param.getStallCheckId());
        if (stallCheck==null) {
            throw new StallException(StallExceptionCode.STALL_CHECK_OBJECT_NOT_EXISTS);//车位审核对象不存在
        }
        if (stallCheck.getStallCheckState()!= StateData.RENTERS_CHECK_NO_PASS) {
            throw new StallException(StallExceptionCode.STALL_CHECK_PASS_OR_WAIT);//审核车位已申请或已通过
        }
        //创建修改对象，修改信息的查询、判断、设置
        UpdateWrapper<StallCheck> wrapper = new UpdateWrapper<>();
        wrapper.eq("stall_check_id",param.getStallCheckId())
                .set("stall_check_state",StateData.RENTERS_CHECK_WAIT);//审核状态
        if (param.getCertifiedInfoId()!=null) {
            wrapper.set("certified_info_id",param.getCertifiedInfoId());
        }
        if (param.getStallType()!=null) {
            wrapper.set("stall_type",param.getStallType());
        }
        if (StringUtils.hasLength(param.getRentersRealName())) {
            wrapper.set("renters_real_name",param.getRentersRealName());
        }
        if (param.getStallInfoNum()!=null) {
            wrapper.set("stall_info_num",param.getStallInfoNum());
        }
        if (StringUtils.hasLength(param.getStallBuyProve())) {
            wrapper.set("stall_buy_prove",param.getStallBuyProve());
        }
        if (StringUtils.hasLength(param.getRentersInfoCard())) {
            wrapper.set("renters_info_card",param.getRentersInfoCard());
        }
        if (StringUtils.hasLength(param.getStallInfoArea())) {
            wrapper.set("stall_info_area",param.getStallInfoArea());
        }
        update(wrapper);
        return true;
    }

    /**
     * rentersId:出租客信息id
     * rentersSelect:出租客查询申请
     * @return RentersSelectStallCheckDTO:出租客查询审核信息返回参数
     * @throws Exception
     */
    @Override
    public RentersSelectStallCheckDTO rentersSelect(Integer rentersId) throws Exception {
        StallCheck stallCheck = getById(rentersId);
        RentersSelectStallCheckDTO dto = BeanUtil.toBean(stallCheck, RentersSelectStallCheckDTO.class);
        if (dto==null) {
            throw new StallException(StallExceptionCode.STALL_CHECK_OBJECT_NOT_EXISTS);//车位审核对象不存在
        }
        return dto;
    }

    /**
     * certifiedSelect:物业分页查询审核
     * @param param:物业分页查询审核信息
     * @return PageInfo:分页对象
     * @throws Exception
     */
    @Override
    public PageInfo certifiedSelect(CertifiedSelectCheckStallParam param) throws Exception {

        //分页参数查询判断
        Long current = pageInfoCheck.currentSet(param.getCurrent());
        Long size = pageInfoCheck.sizeSet(param.getSize());

        //获取：物业信息服务（调用，对象的判断）
        SelectCertifiedInfoDTO certifiedInfoDTO = serveCallClass.certifiedServerCall(param.getCertifiedAccountId());
        if (certifiedInfoDTO==null) {
            throw new StallException(StallExceptionCode.CERTIFIED_INFO_CALL_DTO_NO_EXISTS);//物业信息调用dto不存在
        }
        //创建查询对象
        QueryWrapper<StallCheck> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("certified_info_id",certifiedInfoDTO.getCertifiedInfoId());

        //可选参数判断
        if (param.getStallCheckState()!=null) {
            if ((param.getStallCheckState()== StateData.RENTERS_CHECK_WAIT)
                    ||(param.getStallCheckState()== StateData.RENTERS_CHECK_PASS)
                    ||(param.getStallCheckState()== StateData.RENTERS_CHECK_NO_PASS)) {
                queryWrapper.eq("stall_check_state",param.getStallCheckState());
            }else throw new StallException(StallExceptionCode.STALL_CHECK_STATE_PARAM_ERROR);//车位审核状态参数错误
        }
        if (param.getStallType()!=null) {
            if ((param.getStallType()== StateData.STALL_TYPE_NORMAL)
                    ||(param.getStallType()== StateData.STALL_TYPE_CHARGE)) {
                queryWrapper.eq("stall_type",param.getStallType());
            }else throw new StallException(StallExceptionCode.STALL_CHECK_TYPE_PARAM_ERROR);//车位审核类型参数错误
        }

        //获取：分页中的list集合，转存
        Page<StallCheck> page = stallCheckMapper.selectPage(new Page<StallCheck>(current,size), queryWrapper);
        List<StallCheck> stallCheckList = page.getRecords();
        List<CertifiedSelectStallCheckDTO> dtoList = BeanUtil.copyToList(stallCheckList, CertifiedSelectStallCheckDTO.class);

        //设置分页对象数据
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPages(page.getPages());
        pageInfo.setTotal(page.getTotal());
        pageInfo.setCurrent(page.getCurrent());
        pageInfo.setSize(page.getSize());
        pageInfo.setRecords(dtoList);

        return pageInfo;
    }

    /**
     * platformSelect  平台查询车位审核申请
     * @param param 平台查询车位审核申请参数对象
     * @return PageInfo
     * @throws Exception
     */
    @Override
    public PageInfo platformSelect(PlatformSelectCheckStallParam param) throws Exception {

        //分页参数查询判断
        Long current = pageInfoCheck.currentSet(param.getCurrent());
        Long size = pageInfoCheck.sizeSet(param.getSize());

        //创建查询对象
        QueryWrapper<StallCheck> queryWrapper = new QueryWrapper<>();

        //可选参数判断
        if (param.getCertifiedInfoId()!=null){
            queryWrapper.eq("certified_info_id",param.getCertifiedInfoId());
        }
        if (param.getStallCheckState()!=null) {
            if ((param.getStallCheckState()== StateData.RENTERS_CHECK_WAIT)
                    ||(param.getStallCheckState()== StateData.RENTERS_CHECK_PASS)
                    ||(param.getStallCheckState()== StateData.RENTERS_CHECK_NO_PASS)) {
                queryWrapper.eq("stall_check_state",param.getStallCheckState());
            }else throw new StallException(StallExceptionCode.STALL_CHECK_STATE_PARAM_ERROR);//车位审核状态参数错误
        }
        if (param.getStallType()!=null) {
            if ((param.getStallType()== StateData.STALL_TYPE_NORMAL)
                    ||(param.getStallType()== StateData.STALL_TYPE_CHARGE)) {
                queryWrapper.eq("stall_type",param.getStallType());
            }else throw new StallException(StallExceptionCode.STALL_CHECK_TYPE_PARAM_ERROR);//车位审核类型参数错误
        }
        if (StringUtils.hasLength(param.getRentersRealName())) {
            queryWrapper.like("renters_real_name",param.getRentersRealName());
        }

        //获取：分页中的list集合，转存
        Page<StallCheck> page = stallCheckMapper.selectPage(new Page<StallCheck>(current,size), queryWrapper);
        List<StallCheck> stallCheckList = page.getRecords();
        List<PlatformSelectStallCheckDTO> dtoList = BeanUtil.copyToList(stallCheckList, PlatformSelectStallCheckDTO.class);

        //设置分页对象数据
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPages(page.getPages());
        pageInfo.setTotal(page.getTotal());
        pageInfo.setCurrent(page.getCurrent());
        pageInfo.setSize(page.getSize());
        pageInfo.setRecords(dtoList);

        return pageInfo;
    }


}
